Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

Problem

After PR #273 merged, additional compatibility issues were discovered:

Cannot read properties of undefined (reading 'slice')
at App.tsx:374:29

This occurs when projectConfig.workspaces is undefined due to config format differences between branches.

Root Cause

The config loader uses type assertions without validation:

const projectsMap = new Map<string, ProjectConfig>(
  parsed.projects as Array<[string, ProjectConfig]>
);

If loaded config has ProjectConfig with missing workspaces field, all array operations fail.

Solution

Add ?? [] fallback to all array operations on projectConfig.workspaces:

Files Fixed

App.tsx:

  • Line 242: .find()?? []).find()
  • Line 374: .slice()?? []).slice()

ProjectSidebar.tsx:

  • Line 823: .map()?? []).map()

ipcMain.ts:

  • Line 225: .push() → Initialize if undefined first
  • Line 300: .findIndex()?? []).findIndex()
  • Line 367: Array assignment → Guard with existence check
  • Line 808-810: .length and .filter()?? []).length and ?? []).filter()
  • Line 925-927: .length in error message → ?? []).length

config.ts:

  • Line 185: for...of loop → ?? [])

Testing

  • make typecheck passes
  • make static-check passes
  • ✅ All array operations handle undefined gracefully
  • ✅ Works with both old (no workspaces) and new (with workspaces) configs

Impact

Prevents all .slice(), .map(), .filter(), .find(), .length crashes when switching between branches with different config formats.

Make workspace path access defensive with optional chaining to prevent
crashes when switching between branches with different config formats.

Changes:
- Add optional chaining (?.) to all workspacePath.split() calls
- Provide fallbacks using workspaceId when path is undefined
- Affects App.tsx and utils/commands/sources.ts

This allows the app to work with both:
- Old config format (only 'path' field)
- New config format (with 'id', 'name', and 'path' fields)

Prevents 'Cannot read properties of undefined' errors when config
has fields that the current code version doesn't expect.
Don't render AIView if workspacePath is undefined to prevent crashes
in features that depend on a valid path (like terminal operations).

This ensures we show the welcome screen instead of attempting to render
a workspace view with invalid/missing data.
Guard all workspaces array access with ?? [] fallback to prevent crashes
when config structure differs between branches.

Fixed locations:
- App.tsx: config.workspaces.slice() and .find()
- ProjectSidebar.tsx: config.workspaces.map()
- ipcMain.ts: config.workspaces on findIndex, filter, length, push, array assignment
- config.ts: for...of loop over projectConfig.workspaces

Each location now handles undefined/missing workspaces arrays gracefully,
allowing seamless switching between old and new config formats.
Support reading workspace ID from config when present, falling back to
generated ID when missing. This allows old code (main branch) to work
with new config format (stable-ids branch).

Changes:
- Workspace interface now has optional id, name, createdAt fields
- getAllWorkspaceMetadata() uses stored ID when available
- findWorkspace() checks both stored and generated IDs
- Workspace rename logic checks both ID formats

This fixes the issue where workspaces created on stable-ids branch
(with stable IDs like 'f0e1f76700') don't appear when switching to
main branch (which expects IDs like 'cmux-f0e1f76700').
When metadata.json doesn't exist (workspaces created on newer branches),
reconstruct metadata from config and save it for future use.

This fixes resumeStream errors when switching from stable-ids branch
(which stores metadata in config) to main branch (which expects
metadata.json files).

The fallback:
1. Looks up workspace in config via getAllWorkspaceMetadata()
2. Saves the metadata to metadata.json for future access
3. Returns the metadata so the operation can proceed

This allows seamless switching between branches with different
metadata storage strategies.
Don't check both stored and generated IDs simultaneously - this causes
renamed workspaces to still match their old IDs.

Instead, use stored ID if present, otherwise fall back to generated ID.
This ensures proper separation between old and new workspace identities.

Fixes renameWorkspace integration test failure where old workspace ID
was still resolving after rename.
The renameWorkspace tests were manually adding workspaces to config after
setupWorkspace had already created them via WORKSPACE_CREATE IPC. This
created duplicates in config, causing renamed workspaces to still be found
by their old IDs.

Fixed by removing the redundant manual config manipulation - WORKSPACE_CREATE
already handles both project creation and workspace registration.

This was causing getAllWorkspaceMetadata() to return duplicate IDs, which
made the fallback logic incorrectly find renamed workspaces by their old IDs.
@ammario ammario added this pull request to the merge queue Oct 16, 2025
@ammario ammario removed this pull request from the merge queue due to a manual request Oct 16, 2025
@ammario ammario merged commit c63c6c4 into main Oct 16, 2025
8 checks passed
@ammario ammario deleted the config-robustness branch October 16, 2025 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants